package dk.itu.samd.group2.tagapastry.messages;

import java.io.IOException;
import java.text.DateFormat;
import java.text.ParseException;
import java.util.Date;

import dk.itu.samd.group2.tagapastry.Tag;
import dk.itu.samd.group2.tagapastry.TagapastryImpl;
import rice.p2p.commonapi.Endpoint;
import rice.p2p.commonapi.Id;
import rice.p2p.commonapi.Message;
import rice.p2p.commonapi.NodeHandle;
import rice.p2p.commonapi.rawserialization.InputBuffer;
import rice.p2p.commonapi.rawserialization.OutputBuffer;
import rice.p2p.commonapi.rawserialization.RawMessage;


@SuppressWarnings("serial")
public abstract class TagapastryMsg implements RawMessage {

	protected NodeHandle originalSender;
	protected NodeHandle recepientHandle;
	protected Tag tag;

	@Override
	public int getPriority() {
		return Message.LOW_PRIORITY;
	}
	
	public abstract void execute(TagapastryImpl tagaImpl);
	
	public int getSize() {
		return tag.getSize();
	}
	
	public TagapastryMsg(Tag tag, NodeHandle sender) {
		this(tag, sender, null);
	}
	
	public TagapastryMsg(Tag tag, NodeHandle sender, NodeHandle recepientHandle) {
		this.tag = tag;
		this.originalSender = sender;
		this.recepientHandle = recepientHandle;
	}
	
	public abstract Id getRecepientId();
	
	public NodeHandle getRecepientNodeHandle() {
		return recepientHandle;
	}
	
	// TODO remove
	public Id getSenderId() {
		return originalSender.getId();
	}
	
	public TagapastryMsg(InputBuffer buf, Endpoint endpoint) throws IOException {
		this.originalSender = endpoint.readNodeHandle(buf); 
		boolean hasRecepientHandle = buf.readBoolean();
		if (hasRecepientHandle) {
			this.recepientHandle = endpoint.readNodeHandle(buf); 
		} 
		this.tag = new Tag(buf, endpoint);
	}

	@Override
	public void serialize(OutputBuffer buf) throws IOException {
		originalSender.serialize(buf);
	    buf.writeBoolean(recepientHandle != null);
	    if (recepientHandle != null) {
	    	recepientHandle.serialize(buf);
	    } 
	    tag.serialize(buf);
	}

	public String toString() {
		return "{type : " + this.getClass().getSimpleName() +
		", tag : " + tag +
		", from : " + originalSender.getId() + 
		", to : " + getRecepientId();
	}
	
	public Tag getTag() {
		return tag;
	}
	
	public void setTag(Tag tag) {
		this.tag = tag;
	}
	
}
